package com.example.controller;

import com.example.dto.PageShowDTO;
import com.example.dto.PageTemplateDTO;
import com.example.entity.*;
import com.example.service.ComponentTemplateInstService;
import com.example.service.DataService;
import com.example.service.PageTemplateService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Api(value = "页面实例保存", description = "用于页面实例的增删改查")
@RestController
@RequestMapping("/report/bi/page-templates")
public class PageTemplateController {

    @Autowired
    private PageTemplateService pageTemplateService;


    @Autowired
    private DataService dataService;

    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageTemplateId", value = "当前编辑页的页面ID", required = true),
            @ApiImplicitParam(name = "imageName", value = "图片名称", required = true),
            @ApiImplicitParam(name = "imageBase64", value = "图片数据", required = true),
            @ApiImplicitParam(name = "componentTemplateList", value = "组件JSON信息", required = true),
    })
    @ApiOperation(value= "同时保存详情页组件信息和图片信息")
    @PostMapping("/inst")
    public ResBody<Long> saveComponentAndImage(@RequestBody PageTemplateDTO pageTemplateDTO) {

        return ResBody.success(pageTemplateService.saveComponentAndImage(pageTemplateDTO));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "页面名称", required = true),
            @ApiImplicitParam(name = "routing", value = "页面路由", required = true),
    })
    @ApiOperation(value = "只用于保存页面信息")
    @PostMapping
    public ResBody<Long> create(@RequestBody PageTemplate pageTemplate) {
        return ResBody.success(pageTemplateService.createPageTemplate(pageTemplate));
    }

    @PostMapping("/update")
    public ResBody<Boolean> update(@RequestBody PageTemplate pageTemplate) {
        boolean b = pageTemplateService.updatePageTemplate(pageTemplate);
        if(b){
            return ResBody.success(b);
        }
        return ResBody.error("更新失败");
    }

    @PostMapping("/delete")
    public ResBody<Boolean> delete(@RequestBody PageTemplate pageTemplate) {
        boolean b = pageTemplateService.deletePageTemplate(pageTemplate.getId());
        if(b){
            return ResBody.success(b);
        }
        return ResBody.error("删除失败");
    }

    @GetMapping("/{id}")
    public ResBody getById(@PathVariable Long id) {
        return ResBody.success(pageTemplateService.getPageTemplateById(id));
    }

    @GetMapping
    public ResBody<List<PageTemplate>> getAll() {
        return ResBody.success(pageTemplateService.getAllPageTemplates(""));
    }


    @ApiOperation(value = "返回页面信息")
    @GetMapping("/show")
    public ResBody getAllShow(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String name) {

        List<PageShowDTO> totalData = pageTemplateService.getAllPageInfo(name);

        // 使用PageHelper进行分页
        PageHelper.startPage(pageNum, pageSize);
        List<PageShowDTO> pageShowDTOS = pageTemplateService.getAllPageInfo(name);

//        if (name != null && !name.equals("")) {
//            pageShowDTOS = pageShowDTOS.stream()
//                    .filter(v -> v.getName() != null && v.getName().contains(name)) // 包含关键词
//                    .collect(Collectors.toList());
//        }
        ;
        // 用PageInfo包装结果
        PageInfo<PageShowDTO> pageInfo = new PageInfo<>(pageShowDTOS);
        pageInfo.setTotal(totalData.size());

        return ResBody.success(pageInfo);
    }

    @ApiOperation(value = "返回页面模板信息")
    @GetMapping("/edit")
    public ResBody getAllJsonTemplateInfo(Long templateId) {
//        List<ComponentTemplate> componentTemplates =  componentTemplateInstService.getByPageTemplateId(templateId);
//        List<ComponentTemplate> sortedTemplates = componentTemplates.stream()
//                .sorted(Comparator.comparingInt(ComponentTemplate::getSort))
//                .collect(Collectors.toList());
//
//        List<Map<String, Object>> result = new ArrayList<>();
//        for (ComponentTemplate sortedTemplate : sortedTemplates) {
//            result.add(sortedTemplate.getConfig());
//        }

        PageTemplate pageTemplate = pageTemplateService.getPageTemplateById(templateId);

        // 判断是否还未编辑详情页信息
        if (pageTemplate == null || pageTemplate.getConfig() == null) {
            return ResBody.success();
        }

        return ResBody.success(pageTemplate.getConfig().get("config"));
    }


    @ApiOperation(value = "返回页面组件模板信息以及模板对应的数据信息")
    @PostMapping("/data")
    public ResBody<List<Map<String, Object>>> getAllShowByParam(@RequestBody CommonReqDTO reqDTO) {


        Long templateId = reqDTO.getTemplateId();
        List<Map<String, Object>> componentTemplates =
                (List<Map<String, Object>>)pageTemplateService.getPageTemplateById(templateId).getConfig().get("config");

        for (Map<String, Object> stringObjectMap : componentTemplates) {
            String sqlContent = (String) stringObjectMap.get("setSql");


            Map<String,Object> reqMap = new HashMap<>();
            reqMap.put("reqDTO",reqDTO);
            reqMap.put("sql",sqlContent);

            int templateType = (int)stringObjectMap.get("id");
            List<Map<String, Object>> data = null;
            try{
                data = dataService.getData(reqMap);
            }catch (Throwable th){
                return ResBody.error(
                        "第"+templateType+"个组件执行失败,执行的sql是"+sqlContent.replaceAll("\\n"," "));
            }

            switch (templateType) {
                case 1:
                    stringObjectMap.put("data", data);
                    break;
                case 2: //折线图
                    stringObjectMap.put("data", getSecondData(data,(List<Object>)stringObjectMap.get("items")));
                    break;
                case 3:
                    stringObjectMap.put("data", ListUtils.convertTo2DArrayWithoutHeader(data, (ArrayList<String>)stringObjectMap.get("xName")));
                    break;
                case 4: // 健康度评估
                    stringObjectMap.put("data", getFourthData(data));
                    break;
                case 5:
                    stringObjectMap.put("data", dealDataResult(data));
                    break;
                case 6: // 陈列优化建议
                    stringObjectMap.put("data", dealOptionRecommend(data, (List<Object>)stringObjectMap.get("items")));
                    break;
                case 7: // 策略建议
                    stringObjectMap.put("data", dealStrategy(data));
                    break;
                case 8:
                    stringObjectMap.put("data", dealBusinessAnly(data));
                    break;
                case 9: // 关联强度矩阵
                    stringObjectMap.put("data", doMatrix2(data));
                    break;
                case 10: // 关联强度分析
                    stringObjectMap.put("data", dealReleation(data));
                    break;
                case 11: // 访问来源分析
                    List<Object> result = dealSourceAnalysis(data);
                    stringObjectMap.put("data", result);
                    break;
                case 12:
                    stringObjectMap.put("data", dealLineAndBarChar(data));
                    break;
                case 13:
                    stringObjectMap.put("data",dealLineBar(data, (List<Object>)stringObjectMap.get("items")));
                    break;
                case 15:
                    stringObjectMap.put("data", dealExceptionWarring(data));
                    break;
                default:
                    stringObjectMap.put("data", data);

            }
        }
        return ResBody.success(componentTemplates);






    }

    private Map<String, Object> dealExceptionWarring(List<Map<String, Object>> data) {
        List<List<Object>> result = new ArrayList<>();

        StringBuffer stringBuffer = new StringBuffer();
        for (Map<String, Object> datum : data) {
            String text = (String)datum.get("analysis_text");
            if (!text.equals("")) { // 只处理非空的
                stringBuffer.append("<p>"+text+"</p>");
            }

            List<Object> item = new ArrayList<>();

            item.add(String.valueOf(datum.get("val1")));
            item.add(String.valueOf(datum.get("val2")));
            item.add(String.valueOf(datum.get("val3")));
            item.add(String.valueOf(datum.get("val4")));

            result.add(item);
        }

        Map<String, Object> mapResult = new HashMap<>();
        mapResult.put("vals", result);
        mapResult.put("text", stringBuffer.toString());

        return mapResult;
    }

    private Map<String, Object> dealDataResult(List<Map<String, Object>> data) {
        List<Object> result = new ArrayList<>();

        StringBuffer stringBuffer = new StringBuffer();
        for (Map<String, Object> datum : data) {
            String text = (String)datum.get("analysis_text");
            if (!text.equals("")) { // 只处理非空的
                stringBuffer.append("<p>"+text+"</p>");
            }

            result.add(String.valueOf(datum.get("val")));
        }

        Map<String, Object> mapResult = new HashMap<>();
        mapResult.put("vals", result);
        mapResult.put("text", stringBuffer.toString());

        return mapResult;
    }

    private Map<String, Object> dealBusinessAnly(List<Map<String, Object>> data) {
        List<Map<String, Object>> result = new ArrayList<>();

        StringBuffer stringBuffer = new StringBuffer();
        for (Map<String, Object> datum : data) {
            String text = (String)datum.get("analysis_text");
            stringBuffer.append("<p>"+text+"</p>");

            Map<String, Object> mapData = new HashMap<>();
            mapData.put("val1", String.valueOf(datum.get("val1")));
            mapData.put("val2", String.valueOf(datum.get("val2")));

            result.add(mapData);
        }

        Map<String, Object> mapResult = new HashMap<>();
        mapResult.put("val", result);
        mapResult.put("text", stringBuffer.toString());

        return mapResult;
    }

    private List<Object> dealStrategy(List<Map<String, Object>> data) {
        List<Object> result = new ArrayList<>();
        result.add(data.get(0).get("data"));
        return result;
    }

    private List<Object> dealOptionRecommend(List<Map<String, Object>> data, List<Object> items) {
        List<Object> result = new ArrayList<>();

        for (Object item : items) {
            String name = (String)((LinkedHashMap)((LinkedHashMap) item).get("config")).get("name");

            for (Map<String, Object> datum : data) {
                result.add(datum.get(name));
            }
        }
        return result;
    }

    private List<Map<String, Object>> dealLineBar(List<Map<String, Object>> data, List<Object> items) {
        List<Map<String, Object>> result = new ArrayList<>();

        for (Object item : items) {
            String name = (String)((LinkedHashMap)((LinkedHashMap) item).get("config")).get("name");

            List<Object> resultData = new ArrayList<>();
            List<Object> resultXNames = new ArrayList<>();

            for (Map<String, Object> datum : data) {
                resultData.add(datum.get(name+"_data"));
                resultXNames.add(datum.get(name+"_x"));
            }

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("vals", resultData);
            resultMap.put("xNames", resultXNames);

            result.add(resultMap);
        }
        return result;
    }

    private Map<String, Object> dealLineAndBarChar(List<Map<String, Object>> data) {
        List<List<Object>> result = new ArrayList<>();

        List<Object> xNames = new ArrayList<>(); // 处理X轴数据

        List<Object> item1Result = new ArrayList<>();
        List<Object> item2Result = new ArrayList<>();
        List<Object> item3Result = new ArrayList<>();

        for (Map<String, Object> datum : data) {
            xNames.add(datum.get("xNames"));
            item1Result.add(datum.get("item1"));
            item2Result.add(datum.get("item2"));
            item3Result.add(datum.get("item3"));
        }

        result.add(item1Result);
        result.add(item2Result);
        result.add(item3Result);

        Map<String, Object> mapResult = new HashMap<>();
        mapResult.put("vals", result);
        mapResult.put("xNames", xNames);

        return mapResult;
    }

    private List<Object> dealReleation(List<Map<String, Object>> data) {
        List<Object> xResult = new ArrayList<>();
        List<Object> yResult = new ArrayList<>();

        for (Map<String, Object> datum : data) {
            List<Object> xData = new ArrayList<>();
            List<Object> yData = new ArrayList<>();

            xData.add(((Number)datum.get("x1")).intValue());
            xData.add(((Number)datum.get("y1")).intValue());
            xData.add(((Number)datum.get("value1")).intValue());
            xData.add(datum.get("title"));

            xResult.add(xData);

            yData.add(((Number)datum.get("x2")).intValue());
            yData.add(((Number)datum.get("y2")).intValue());
            yData.add(((Number)datum.get("value2")).intValue());
            yData.add((datum.get("title")));

            yResult.add(yData);
        }

        List<Object> result = new ArrayList<>();
        result.add(xResult);
        result.add(yResult);
        return result;
    }

    private List<Object> dealSourceAnalysis(List<Map<String, Object>> data) {
        List<Object> result = new ArrayList<>();

        for (Map<String, Object> datum : data) {
            result.add(datum.get("value"));
        }

        return result;
    }


    //  处理折线图数据
    private Map<String, Object> getSecondData(List<Map<String, Object>> data,List<Object> items){


        List<String> nameList = new ArrayList<>();

        for (Object item : items) {
            String name = (String)((LinkedHashMap)((LinkedHashMap) item).get("config")).get("name");
            nameList.add(name);
        }


        List<String> xName = data.stream().map(e -> e.get("date").toString()).distinct().sorted().collect(Collectors.toList());
//        List<String> yAxis = data.stream().map(e -> e.get("region").toString()).distinct().sorted().collect(Collectors.toList());
        List<String> yAxis = nameList;
        List<List<String>> vals = new ArrayList<>();
        yAxis.forEach(region -> {
            List<String> collect = data.stream().filter(e -> e.get("region").toString().equals(region)).map(e -> e.get("sales_amount").toString()).collect(Collectors.toList());
            vals.add(collect);
        });
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("xName",xName);
        result.put("vals",vals);
        return result;
    }


    //  处理雷达图数据
    private List<Map<String,Object>> getFourthData(List<Map<String, Object>> data){
        List<Map<String,Object>> result = new ArrayList<>();
        data.forEach(e->{
            Map<String,Object> map = new HashMap<>();
            map.put("dimensionVal",e.get("act_val"));
            map.put("percentage",e.get("alarm_val"));
            result.add(map);
        });
        return result;
    }


    private List<Map<String,Object>> doMatrix2(List<Map<String, Object>> list) {

        List<Map<String,Object>> results =  new ArrayList<>();

        List<String> typeList = list.stream().map(e -> e.get("type").toString()).distinct().collect(Collectors.toList());

        Map<String, List<Map<String, Object>>> typeMap = list.stream().collect(Collectors.groupingBy(e -> e.get("type").toString()));

        typeList.forEach(e->{
            List<String> xName = typeMap.get(e).stream().map(f -> f.get("x_col").toString()).distinct().collect(Collectors.toList());
            List<String> yName = typeMap.get(e).stream().map(f -> f.get("y_col").toString()).distinct().collect(Collectors.toList());
            List<List<Integer>> data = typeMap.get(e).stream().map(f -> {
                List<Integer> tempList = new ArrayList<>();
                tempList.add(((Number) f.get("x_val")).intValue());
                tempList.add(((Number) f.get("y_val")).intValue());
                tempList.add(((Number) f.get("show_value")).intValue());
                return tempList;
            }).collect(Collectors.toList());
            Map<String, Object> map = new HashMap<>();
            map.put("data",data);
            map.put("xName",xName);
            map.put("yName",yName);
            results.add(map);
        });
        return results;
    }



/*
    @ApiOperation(value = "返回页面组件模板信息以及模板对应的数据信息")
    @GetMapping("/data")
    public ResBody getAllShow(Long templateId) {
//        List<ComponentTemplate> componentTemplates =  componentTemplateInstService.getByPageTemplateId(templateId);
//        List<ComponentTemplate> sortedTemplates = componentTemplates.stream()
//                .sorted(Comparator.comparingInt(ComponentTemplate::getSort))
//                .collect(Collectors.toList());
//
//        List<Map<String, Object>> sortedResult = new ArrayList<>();
//        for (ComponentTemplate sortedTemplate : sortedTemplates) {
//            sortedResult.add(sortedTemplate.getConfig());
//        }
//
//        List<List<Map<String, Object>>> result = new ArrayList<>();
//        for (Map<String, Object> stringObjectMap : sortedResult) {
//            String sqlContent = (String) stringObjectMap.get("setSql");
//            List<Map<String, Object>> data = dataService.getData(sqlContent);
//            result.add(data);
//        }

        return ResBody.success(pageTemplateService.getPageTemplateById(templateId));
    }*/



//    @GetMapping("/search")
//    public Result<List<PageTemplate>> search(PageTemplate condition) {
//        return Result.success(pageTemplateService.getPageTemplatesByCondition(condition));
//    }



//    @ApiOperation(value = "销售趋势折线图数据")
//    @PostMapping("/sellData")
//    public ResBody sellData() {
//        String sqlContent = "SELECT date, sales_amount , region    FROM  bi_t_sell;";
//        Map<String,Object> reqMap = new HashMap<>();
//        reqMap.put("reqDTO",new CommonReqDTO());
//        reqMap.put("sql",sqlContent);
//        List<Map<String, Object>> data = dataService.getData(reqMap);
//        Map<String, Object> result = getSecondData(data);
//        return  ResBody.success(result);
//    }
//
//
//    @ApiOperation(value = "健康雷达图")
//    @PostMapping("/healthData")
//    public ResBody healthData() {
//        String sqlContent = "SELECT  act_val, alarm_val from bi_t_health";
//        Map<String,Object> reqMap = new HashMap<>();
//        reqMap.put("reqDTO",new CommonReqDTO());
//        reqMap.put("sql",sqlContent);
//        List<Map<String, Object>> data = dataService.getData(reqMap);
//        List<Map<String, Object>> fourthData = getFourthData(data);
//        return  ResBody.success(fourthData);
//    }

//    @GetMapping("/search")
//    public Result<List<PageTemplate>> search(PageTemplate condition) {
//        return Result.success(pageTemplateService.getPageTemplatesByCondition(condition));
//    }
}
